package com.runvp.netty.decoder;

import com.alibaba.fastjson.JSONObject;
import com.runvp.common.enums.NettyCmd;
import com.runvp.common.model.tcp.MessageParseBody;
import com.runvp.common.model.tcp.MessageReceiveBody;
import com.runvp.common.model.tcp.SectionRule;
import com.runvp.common.util.enc.aes128gcm.Aes128GcmUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;

import static com.runvp.common.hex.CommonHandleUtils.substrByRule;
import static com.runvp.netty.common.ByteUtils.encodeHexStr;
import static com.runvp.netty.constant.ConstantBytes.DIVIDE_BY_NUMBER;

/**
 * *
 * ConversionDecoder 解码器
 *
 *
 * @author xkk
 * @Date 2020/07/13 07:13
 **/
@Slf4j
public class ConversionDecoder extends ByteToMessageDecoder {

    public static void main(String[] args) {
        String result = "3A3A040100000000003E0100616BE31427FC79114ED9A77DA48498933CFBB0CA4CDE386537DD4FFE13A99D69E149A2D50B9E132FA80E80D909A0AC259D447DC0CAA39F867A092660FB182F7C6ACDE797B15A8D87C7AF9111D9A6469D7B7F1BAE21247A52B4FD08F54745CB3D63AAFC435D535D0FBEE45A10022562462EB8";
        result = "3A3A03080000000000000100126BE3053DBA611A40CBF13CB78E9A892CA0B414CDAB76CD419245BFEC13114B1F7BD4";
        result = "3A3A030A0000000000000100676BE3093DBA611A4088A160F4DB9A8D2FB5F0DA4FCF3F6D37DE59E313E8D23BB449A8D10590413CEE1688CD16A2B6259D5D619BD2BB9D9B6815343DBE18712B2BD6FF8ABF0B8DD08FAF9B16CAB35DCD337F40FA6C3F795BA3E11BA90B08902E69E6D89D44F535E2DCE97501160EE845D632B6FE78CF5C96" ;
        System.out.println("解析结果:"+JSONObject.toJSONString(parseMessage(result)));
    }

    /**
     * 解析报文
     * @param result
     * @return MessageParseBody
     */
    public static MessageReceiveBody parseMessage(String result){
        int rl = result.length();
        MessageReceiveBody parseBody = new MessageReceiveBody();
        parseBody.setTime(new Date());
        parseBody.setHead(substrByRule(result, SectionRule.head));
        parseBody.setType(substrByRule(result,SectionRule.type));
        parseBody.setCmd(substrByRule(result,SectionRule.cmd));
        log.info("1-本次接收处理指令【{}】",NettyCmd.getDesc(parseBody.getType(),parseBody.getCmd()));
        parseBody.setDid(substrByRule(result,SectionRule.did()));
        parseBody.setVersion(substrByRule(result,SectionRule.version()));
        parseBody.setLength(substrByRule(result,SectionRule.length()));
        parseBody.setBody(substrByRule(result,SectionRule.body(rl)));
        parseBody.setTag(substrByRule(result,SectionRule.tag(rl)));
        JSONObject json = JSONObject.parseObject(Aes128GcmUtils.getInstance().setMyKey("BMrcujdO0XDjvOOa").setMyIv("98BPRR4Wve41").decrypt(parseBody.getBody()+parseBody.getTag()));
        parseBody.setBodyJson(json);
        parseBody.setTerminalId(json.getString("sn"));
        parseBody.setTy(json.getString("ty"));
        return parseBody;
    }



    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) {
        try {
//            log.info("<<<<===============解码开始===============>>>>");
//            log.info("原始报文 :" + in.toString());
            byte[] writerIndexByte = new byte[in.writerIndex()];
            in.readBytes(writerIndexByte);
            String result = encodeHexStr(writerIndexByte);
            log.info("1-接收的原始数据包为: {}" , result);
            //可读字节数 < 最小字节数  可读字节不是 2 的倍数 false 抛出异常
            if (result.length() % DIVIDE_BY_NUMBER != 0) {
                log.error("1-报文异常 ： 【报文长度为"+result.length()+" 不是2的倍数】");
                return;
            }
            MessageParseBody parseBody = parseMessage(result);
            log.info("1-decode报文解析结果：{}",JSONObject.toJSONString(parseBody));
//            log.info("<<<<===============解码结束===============>>>>");
            out.add(parseBody);
        } catch (Exception e) {
            log.error("1-<<<<===============解码异常===============>>>> :{}",e.getMessage());
        }
    }
}
